/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.foxline.clinicplus.manager;

import br.com.foxline.clinicplus.enums.*;
import br.com.foxline.clinicplus.service.ContaBancariaServico;
import br.com.foxline.clinicplus.service.DiaryService;
import br.com.foxline.clinicplus.service.IncomeService;
import br.com.foxline.clinicplus.vo.VoDreDespesas;
import br.com.foxline.clinicplus.vo.VoDreReceitas;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.LineChartSeries;
import org.primefaces.model.chart.PieChartModel;

/**
 *
 * @author roniere
 */
@ManagedBean
@ViewScoped
public class ManagerDre implements Serializable {


    @EJB
    DiaryService diaryService;
    @EJB
    IncomeService incomeService;
    @EJB
    ContaBancariaServico contaBancariaServico;
    private Date dateInitial;
    private Date dateFinal;
    private List<VoDreDespesas> voDreDespesas;
    private List<VoDreReceitas> voDreReceitas;
    private BigDecimal geralReceitas;
    private BigDecimal geralDespesas;
    private PieChartModel graficoSaida;
    private PieChartModel graficoEntrada;
    private CartesianChartModel linearProcedureDate;
    private Long max;
    private LineChartSeries serieConsulta;
    private LineChartSeries seriesExame;

    @PostConstruct
    public void init() {
        max = 0L;
        graficoEntrada = new PieChartModel();
        graficoSaida = new PieChartModel();
        graficoEntrada.set("", 1);
        graficoSaida.set("", 1);
        
        linearProcedureDate = new CartesianChartModel();

        serieConsulta = new LineChartSeries("Consultas");
        seriesExame = new LineChartSeries("Exames");

        serieConsulta.set("A", 1);
        seriesExame.set("B", 1);

        linearProcedureDate.addSeries(serieConsulta);
        linearProcedureDate.addSeries(seriesExame);
        
    }

    public void calcReceitas() {
        graficoEntrada.clear();
        voDreReceitas = new ArrayList<VoDreReceitas>();
        geralReceitas = BigDecimal.ZERO;

        for (TypeProcedure tp : TypeProcedure.values()) {
            BigDecimal valueIncomeGeneric = incomeService.getValueIncomeGeneric(null, null, null, dateInitial, dateFinal, null, null, TypeIncome.C, null, null, null, null, null, tp, null, null, null);
            geralReceitas = geralReceitas.add(valueIncomeGeneric);
        }

        for (TypeProcedure tp : TypeProcedure.values()) {
            BigDecimal valueIncomeGeneric = incomeService.getValueIncomeGeneric(null, null, null, dateInitial, dateFinal, null, null, TypeIncome.C, null, null, null, null, null, tp, null, null, null);

            BigDecimal porc = BigDecimal.ZERO;
            if (valueIncomeGeneric != null && valueIncomeGeneric.compareTo(BigDecimal.ZERO) > 0) {
                porc = (valueIncomeGeneric.multiply(new BigDecimal("100"))).divide(geralReceitas, 2, RoundingMode.HALF_EVEN);
            }

            gerarGraficoEntrada(tp.getName(), porc);
            voDreReceitas.add(new VoDreReceitas(tp, valueIncomeGeneric, porc));
        }
    }

    public void calcDespesas() {
        graficoSaida.clear();
        voDreDespesas = new ArrayList<VoDreDespesas>();

        geralDespesas = incomeService.getValueIncomeGeneric(null, null, null, dateInitial, dateFinal, null, null, TypeIncome.D, null, null, null, null, null, null, null, null, null);

        for (TypeDebt td : TypeDebt.values()) {
            BigDecimal valueIncomeGeneric = incomeService.getValueIncomeGeneric(null, null, null, dateInitial, dateFinal, null, null, TypeIncome.D, td, null, null, null, null, null, null, null, null);

            BigDecimal porc = BigDecimal.ZERO;
            if (valueIncomeGeneric != null && valueIncomeGeneric.compareTo(BigDecimal.ZERO) > 0) {
                porc = (valueIncomeGeneric.multiply(new BigDecimal("100"))).divide(geralDespesas, 2, RoundingMode.HALF_EVEN);
            }

            gerarGraficoSaida(td.getDesc(), porc);
            voDreDespesas.add(new VoDreDespesas(td, valueIncomeGeneric, porc));
        }
    }

    public void initial() {
        Calendar gc = GregorianCalendar.getInstance();
        if (dateInitial != null) {
            gc.setTime(dateInitial);
        }
        gc.set(GregorianCalendar.HOUR_OF_DAY, 0);
        gc.set(GregorianCalendar.MINUTE, 0);
        gc.set(GregorianCalendar.SECOND, 0);
        gc.set(GregorianCalendar.MILLISECOND, 0);

        Calendar gc1 = GregorianCalendar.getInstance();
        if (dateInitial != null) {
            gc1.setTime(dateInitial);
            gc1.set(GregorianCalendar.HOUR_OF_DAY, 23);
            gc1.set(GregorianCalendar.MINUTE, 59);
            gc1.set(GregorianCalendar.SECOND, 59);
            gc1.set(GregorianCalendar.MILLISECOND, 59);
        } else {
            gc1.add(GregorianCalendar.DAY_OF_MONTH, 1);
            gc1.set(GregorianCalendar.HOUR_OF_DAY, 0);
            gc1.set(GregorianCalendar.MINUTE, 0);
            gc1.set(GregorianCalendar.SECOND, 0);
            gc1.set(GregorianCalendar.MILLISECOND, 0);
        }
    }

    public void gerar() {
        initial();
        calcDespesas();
        calcReceitas();
        initLinearModel();
        System.err.println(voDreReceitas);
        System.err.println(voDreDespesas);

    }

    public void imprimir() {
        incomeService.dre(voDreDespesas, voDreReceitas, geralReceitas, geralDespesas);
    }

    public Date getDateFinal() {
        return dateFinal;
    }

    public void setDateFinal(Date dateFinal) {
        this.dateFinal = dateFinal;
    }

    public Date getDateInitial() {
        return dateInitial;
    }

    public void setDateInitial(Date dateInitial) {
        this.dateInitial = dateInitial;
    }

    public PieChartModel getGraficoEntrada() {
        return graficoEntrada;
    }

    public void setGraficoEntrada(PieChartModel graficoEntrada) {
        this.graficoEntrada = graficoEntrada;
    }

    public PieChartModel getGraficoSaida() {
        return graficoSaida;
    }

    public void setGraficoSaida(PieChartModel graficoSaida) {
        this.graficoSaida = graficoSaida;
    }

    public void gerarGraficoSaida(String name, BigDecimal valor) {
        graficoSaida.set(name, valor);
    }

    public void gerarGraficoEntrada(String name, BigDecimal valor) {
        graficoEntrada.set(name, valor);
    }
    
     private CartesianChartModel initLinearModel() {

        Calendar gc = GregorianCalendar.getInstance();
        gc.setTime(dateInitial);
        
        gc.set(GregorianCalendar.HOUR_OF_DAY, 0);
        gc.set(GregorianCalendar.MINUTE, 0);
        gc.set(GregorianCalendar.SECOND, 0);
        gc.set(GregorianCalendar.MILLISECOND, 0);
        gc.set(GregorianCalendar.DAY_OF_MONTH, 1);

        Calendar gc1 = GregorianCalendar.getInstance();
        gc1.setTime(dateFinal);
        gc1.set(GregorianCalendar.HOUR_OF_DAY, 23);
        gc1.set(GregorianCalendar.MINUTE, 59);
        gc1.set(GregorianCalendar.SECOND, 59);
        gc1.set(GregorianCalendar.MILLISECOND, 59);


        gc1.set(GregorianCalendar.DAY_OF_MONTH, gc.getActualMaximum(Calendar.DAY_OF_MONTH));

        Locale brasil = new Locale("pt", "BR");
        SimpleDateFormat sdf = new SimpleDateFormat("MMMMM", brasil);

        int mesAtual = gc1.get(GregorianCalendar.MONTH) - gc.get(GregorianCalendar.MONTH);
        
        System.err.println(mesAtual);
        for (int i = 0; i <= mesAtual; i++) {

            Long exame = diaryService.getValueIncomeGeneric(null, null, null, gc.getTime(), gc1.getTime(), null,
                    null, TypeIncome.C, null, null, null, null, null,
                    TypeProcedure.EXAME, null);

            Long consulta = diaryService.getValueIncomeGeneric(null, null, null, gc.getTime(), gc1.getTime(), null,
                    null, TypeIncome.C, null, null, null, null, null,
                    TypeProcedure.CONSULTA, null);

            if (max < exame) {
                max = exame;
            }
            if (max < consulta) {
                max = consulta;
            }

            seriesExame.set(sdf.format(gc.getTime()), exame);
            serieConsulta.set(sdf.format(gc.getTime()), consulta);

            gc.add(GregorianCalendar.MONTH, 1);
            gc1.add(GregorianCalendar.MONTH, 1);
            gc1.set(GregorianCalendar.DAY_OF_MONTH, gc.getActualMaximum(Calendar.DAY_OF_MONTH));

        }
        max += 50;
        linearProcedureDate.addSeries(serieConsulta);
        linearProcedureDate.addSeries(seriesExame);
        return linearProcedureDate;
    }

    public CartesianChartModel getLinearProcedureDate() {
        return linearProcedureDate;
    }

    public void setLinearProcedureDate(CartesianChartModel linearProcedureDate) {
        this.linearProcedureDate = linearProcedureDate;
    }

    public Long getMax() {
        return max;
    }

    public void setMax(Long max) {
        this.max = max;
    }
     
}
